package com.station.http;

import android.support.annotation.NonNull;
import android.util.Log;

import com.station.listener.HttpListener;
import com.station.listener.RxHttpListener;
import com.station.listener.UpImageListener;
import com.station.util.GsonUtil;
import com.station.util.Static;
import com.station.xml.XmlResult;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by nbzl on 2017/7/27.
 */
public class MNetHttp {
    public static MNetHttp mNetHttp;
    public static OkHttpClient client;
    public final static int CONNECT_TIMEOUT = 25 * 1000;
    public final static int READ_TIMEOUT = 25 * 1000;
    public final static int WRITE_TIMEOUT = 25 * 1000;

    public static MNetHttp getInstance() {
        if (mNetHttp == null) {
            mNetHttp = new MNetHttp();
            mNetHttp.client = new OkHttpClient.Builder()
                    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
                    .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                    .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS).build();
        }
        return mNetHttp;
    }

    public void postRequest(String url, Map<String, String> map, final HttpListener listener) {
        Request request;
        if (map.isEmpty()) {
            request = new Request.Builder().url(url).build();
        } else {
            FormBody.Builder builder = new FormBody.Builder();

            for (Map.Entry<String, String> entry : map.entrySet()) {
                builder.add(entry.getKey(), entry.getValue());
            }
            request = new Request.Builder().url(url).post(builder.build()).build();
        }


        //   Request
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                listener.fail("网络异常");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String xml = response.body().string();
                Log.e("Mytext", "-->" + xml);
                listener.success(xml);
            }
        });
    }

    //flag：true (json)
    public void rxPostRequest(final String url, final Map<String, String> datamap, final Class<?> clazz, final boolean flag, final HttpListener listener) {
        Observable.fromArray(url)
                .subscribeOn(Schedulers.io())
                .map(new io.reactivex.functions.Function<String, Map<String, Object>>() {
                    @Override
                    public Map<String, Object> apply(@io.reactivex.annotations.NonNull String s) throws Exception {
                        Map<String, Object> map = new HashMap<String, Object>();
                        try {
                            //Request request;
                            /*if (datamap.isEmpty()) {
                                request = new Request.Builder().url(s).build();
                            } else {
                                MultipartBuilder builder = new MultipartBuilder();
                                for (Map.Entry<String, String> entry : datamap.entrySet()) {
                                    builder.addFormDataPart(entry.getKey(), entry.getValue());
                                }
                                request = new Request.Builder().url(s).post(builder.build()).build();
                            }*/
                            //MultipartBuilder builder = new MultipartBuilder();
                            FormBody.Builder builder = new FormBody.Builder();
                            for (Map.Entry<String, String> entry : datamap.entrySet()) {
                                if(entry.getValue()==null){}else if(entry.getValue().equals("无")){}else if(entry.getValue().equals("请选择")){}else{
                                    builder.add(entry.getKey(), entry.getValue());
                                }
                            }
                            Request request = new Request.Builder().url(s).post(builder.build()).build();
                            Response response = client.newCall(request).execute();
                            String xml = response.body().string();
                            Log.e("Mytext", "-->" + xml);
                            //XmlResult result= XmlResult.newInstance(clazz).fromXml(xml,"detail");
                            Object obj = null;
                            if (flag) {
                                obj = GsonUtil.getInstance().getObject(xml, clazz);
                            } else {
                                obj = XmlResult.newInstance(clazz).fromXml(xml, "detail");
                            }
                            map.put("xml", xml);
                            map.put("data", obj);
                        } catch (Exception e) {
                            Log.e("Mytext", "e-->" + e.toString());
                        }
                        return map;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Map<String, Object>>() {
                    @Override
                    public void onNext(@NonNull Map<String, Object> o) {
                        if (o.size() == 0) {
                            listener.fail(Static.NET_ERROR);
                        } else if (o.get("data") == null) {
                            listener.fail(Static.DATA_ERROR);
                        } else {
                            listener.success(o.get("data"));
                        }
                    }

                    @Override
                    public void onComplete() {
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        listener.fail(Static.DATA_ERROR);
                    }

                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                    }
                });
    }

    //json 默认
    public void rxPostRequest(final String url, final Map<String, String> datamap, final Class<?> clazz, final HttpListener listener) {
        rxPostRequest(url, datamap, clazz, true, listener);
    }

    public void rxListRequest(final List<Map<String, Object>> datamap, final RxHttpListener listener) {
        Observable.fromIterable(datamap)
                .subscribeOn(Schedulers.io())
                .map(new Function<Map<String, Object>, String>() {

                    @Override
                    public String apply(@io.reactivex.annotations.NonNull Map<String, Object> datamap) throws Exception {
                        String url=datamap.get("url").toString();
                        Map<String,String> params=(Map<String, String>) datamap.get("param");
                        FormBody.Builder builder = new FormBody.Builder();
                        for (Map.Entry<String, String> entry : params.entrySet()) {
                            if(entry.getValue()==null){}else if(entry.getValue().equals("无")){}else if(entry.getValue().equals("-1")){}else{
                                builder.add(entry.getKey(), entry.getValue());
                            }

                        }
                        Request request = new Request.Builder().url(url).post(builder.build()).build();
                        Response response = client.newCall(request).execute();
                        String xml = response.body().string();
                        return xml;
                    }
                })
                .filter(new Predicate<String>() {

                    @Override
                    public boolean test(@io.reactivex.annotations.NonNull String s) throws Exception {
                        if (s == null || s.equals("")) {
                            datamap.clear();
                            return false;
                        }
                        return true;

                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>(){

                    @Override
                    public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@io.reactivex.annotations.NonNull String s) {
                        listener.next(s);
                    }

                    @Override
                    public void onError(@io.reactivex.annotations.NonNull Throwable e) {
                        listener.fail("网络异常,加载失败");
                    }

                    @Override
                    public void onComplete() {
                        listener.finish();
                    }
                });


    }


    public void rxUpBitmap(final String url, final List<String> filepath, final Map<String, String> mapParam, final Class zclass, final UpImageListener listener) {
        listener.start();
        Observable.fromIterable(filepath)
                .subscribeOn(Schedulers.io())
                .map(new Function<String, Map<String, String>>() {

                    @Override
                    public Map<String, String> apply(@io.reactivex.annotations.NonNull String path) {
                        File file = new File(path);
                        if (!file.exists()) {
                            return null;
                        } else {
                            Map<String, String> map = new HashMap<String, String>();

                            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
                            MultipartBody.Builder requestBuilder = new MultipartBody.Builder()
                                    .setType(MultipartBody.FORM)
                                    .addPart(Headers.of(
                                            "Content-Disposition",
                                            "form-data; name=\"mFile\"; filename=\"" + file.getName() + "\""), fileBody);


                            for (Map.Entry<String, String> entry : mapParam.entrySet()) {
                                requestBuilder.addFormDataPart(entry.getKey(), entry.getValue().toString());
                            }
                            if (filepath.indexOf(path) == (filepath.size() - 1)) {
                                map.put("end", "1");
                            } else {
                                map.put("end", "0");
                            }
                            Request request = new Request.Builder().url(url).post(requestBuilder.build()).build();
                            Response response = null;
                            try {
                                response = client.newCall(request).execute();
                                String xml = response.body().string();
                                map.put("data", xml);
                                return map;
                            } catch (IOException e) {
                                e.printStackTrace();

                            }


                            return null;
                        }

                    }
                })
                .filter(new Predicate<Map<String, String>>() {

                    @Override
                    public boolean test(Map<String, String> map) throws Exception {
                        if (map == null) {
                            listener.failure("上传文件不存在");
                            filepath.clear();
                            return false;
                        } else if (map.get("data") == null || (map.get("data").equals(""))) {
                            listener.failure("上传文件失败");
                            filepath.clear();
                            return false;
                        } else {
                            return true;
                        }

                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Map<String, String>>() {

                    @Override
                    public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@io.reactivex.annotations.NonNull Map<String, String> data) {
                        Log.e("Mytext", "onNext-->" + data.get("data"));
                        Object resultObj = GsonUtil.getInstance().getObject(data.get("data"), zclass);
                        listener.success(resultObj);
                        if (data.get("end").equals("1")) {
                            Log.e("Mytext", "end-->");
                            listener.complete();
                        }
                    }

                    @Override
                    public void onError(@io.reactivex.annotations.NonNull Throwable e) {
                        //listener.failure("");
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

}
